package com.yeyaomai.dksns.flowis.quartz;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.query.Criteria;

import com.yeyaomai.dksns.flowis.dao.DetailDao;
import com.yeyaomai.dksns.flowis.dao.EngineDao;
import com.yeyaomai.dksns.flowis.dao.EngineKeywordDao;
import com.yeyaomai.dksns.flowis.dao.KeywordDao;
import com.yeyaomai.dksns.flowis.domain.Engine;
import com.yeyaomai.dksns.flowis.domain.EngineKeyword;
import com.yeyaomai.dksns.flowis.domain.Keyword;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisStatDetailDTO;
import com.yeyaomai.dksns.flowis.util.CollectionNames;
import com.yeyaomai.dksns.flowis.util.VelocityToolDateUtils;

/**
 * 
 * 定时从mongo取数据，处理搜索引擎与关键字模块数据后添加入MYSQL
 * 
 * @author zhaocm
 * 
 */
public class EngineKeywordExecuto {

	@Resource
	private DetailDao detailDao;

	@Resource
	private KeywordDao keywordDao;
	
	@Resource
	private EngineDao engineDao;

	@Resource
	private EngineKeywordDao engineKeywordDao;
	
	
	public void engineKeywordTiming() throws ParseException {

		String st = VelocityToolDateUtils.getHour(-1);
		String et = VelocityToolDateUtils.getHour(0);
		String stday = VelocityToolDateUtils.getDay(0);
		String etday = VelocityToolDateUtils.getDay(1);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		
		final Logger logger = Logger.getLogger("quartz");

		GroupByResults<Keyword> keywords = this.groupKeyword(st, et);

		if (keywords.getKeys() != 0) {
			for (Keyword keyword : keywords) {

				keyword.setDate(sdf.parse(stday));
				keyword.setUniqueVisitors(this.groupUv(stday, etday,
						CollectionNames.KEYWORD, keyword.getKeyword(), false));
				keyword.setNewUniqueVisitors(this.groupNewUv(stday, etday,
						CollectionNames.KEYWORD, keyword.getKeyword()));
				keyword.setIp(this.groupIp(stday, etday, CollectionNames.KEYWORD,
						keyword.getKeyword(), false));
				keywordDao.addKeyword(keyword);

				GroupByResults<EngineKeyword> engineKeywords = this
						.groupEngineKeyword(st, et, keyword.getKeyword());

				if (engineKeywords.getKeys() != 0) {
					for (EngineKeyword ek : engineKeywords) {

						ek.setDate(sdf.parse(stday));
						ek.setKeyword(keyword.getKeyword());
						engineKeywordDao.addEngineKeyword(ek);
					}
				}
			}
		}
		logger.info(" 搜索关键字统计： 统计时间："+sd.format(new Date())+"   记录数据："+keywords.getKeys()+"条");
		
		GroupByResults<Engine> engines = this.groupEngine(st, et);
		if (engines.getKeys() != 0) {
			for (Engine engine : engines) {

				engine.setDate(sdf.parse(stday));
				engine.setUniqueVisitors(this.groupUv(stday, etday,
						CollectionNames.ENGINENAME, engine.getEngineName(), true));
				engine.setIp(this.groupIp(stday, etday, CollectionNames.ENGINENAME,
						engine.getEngineName(), true));
				engineDao.addEngine(engine);
			}
		}
		logger.info(" 搜索引擎统计： 统计时间："+sd.format(new Date())+"   记录数据："+engines.getKeys()+"条");
	}

	//关键系  搜索次数
	public GroupByResults<Keyword> groupKeyword(String st, String et) {

		String mapFunction = "{searchCount : 0 }";
		String reduceFunction = "function(key,values){values.keyword, values.searchCount +=1 }";
		List<String> list = new ArrayList<String>();
		list.add("null");
		list.add("");
		Criteria criteria = Criteria.where("keyword").nin(list).and("engineName").nin(list)
				.and("access_date").gte(st).lt(et);
		return detailDao.group(criteria, CollectionNames.KEYWORD, mapFunction,
				reduceFunction, Keyword.class);
	}

	// 搜索引擎 搜索次数
	public GroupByResults<Engine> groupEngine(String st, String et) {

		String mapFunction = "{searchCount : 0 }";
		String reduceFunction = "function(key,values){values.engineName, values.searchCount +=1 }";
		List<String> list = new ArrayList<String>();
		list.add("null");
		list.add("");
		Criteria criteria = Criteria.where("engineName").nin(list).and("keyword").nin(list)
				.and("access_date").gte(st).lt(et);
		return detailDao.group(criteria, CollectionNames.ENGINENAME,
				mapFunction, reduceFunction, Engine.class);
	}

	// 搜索引擎对应关键字 搜索次数
	public GroupByResults<EngineKeyword> groupEngineKeyword(String st,
			String et, String keyword) {

		String mapFunction = "{searchCount : 0 }";
		String reduceFunction = "function(key,values){values.engineName, values.searchCount +=1 }";
		List<String> list = new ArrayList<String>();
		list.add("null");
		list.add("");
		Criteria criteria = Criteria.where("engineName").nin(list)
				.and("access_date").gte(st).lt(et).and("keyword").is(keyword);
		return detailDao.group(criteria, CollectionNames.ENGINENAME,
				mapFunction, reduceFunction, EngineKeyword.class);
	}

	// 对应关键字或搜索引擎下的 UV数
	private int groupUv(String st, String et, String name, String value, boolean bool) {

		String mapFunction = "{ cookieId: 0}";
		String reduceFunction = "function(key,values) {values.cookieId+=1}";
		Criteria criteria = Criteria.where("cookieId").ne("null")
				.and("access_date").gte(st).lt(et).and(name).is(value);
		List<String> list = new ArrayList<String>();
		list.add("null");
		list.add("");
		if(bool)  criteria.and("keyword").nin(list);
		else criteria.and("engineName").nin(list);
		return detailDao.group(criteria, CollectionNames.COOKIEID, mapFunction,
				reduceFunction, FlowisStatDetailDTO.class).getKeys();
	}

	// 对应关键字或搜索引擎下的 newUV数
	private int groupNewUv(String st, String et, String name, String value) {

		String mapFunction = "{ cookieId: 0}";
		String reduceFunction = "function(key,values) {values.cookieId+=1}";
		List<String> list = new ArrayList<String>();
		list.add("null");
		list.add("");
		Criteria criteria = Criteria.where("visitCount").is(1).and("engineName").nin(list)
				.and("access_date").gte(st).lt(et).and(name).is(value);
		return detailDao.group(criteria, CollectionNames.COOKIEID, mapFunction,
				reduceFunction, FlowisStatDetailDTO.class).getKeys();
	}

	// 对应关键字或搜索引擎下的 IP数
	private int groupIp(String st, String et, String name, String value, boolean bool) {

		String mapFunction = "{ ip: 0}";
		String reduceFunction = "function(key,values) {values.ip+=1}";
		Criteria criteria = Criteria.where("ip").ne("null").and("access_date")
				.gte(st).lt(et).and(name).is(value);
		List<String> list = new ArrayList<String>();
		list.add("null");
		list.add("");
		if(bool)  criteria.and("keyword").nin(list);
		else criteria.and("engineName").nin(list);
		return detailDao.group(criteria, CollectionNames.IP, mapFunction,
				reduceFunction, FlowisStatDetailDTO.class).getKeys();
	}
}